<template>
  <el-form label-width="120px">
    <el-form-item label="SPU名称">
      <el-input
        placeholder="请输入SPU名称"
        v-model="spuParams.spuName"
      ></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌" size="normal">
      <el-select placeholder="请选择" clearable v-model="spuParams.tmId">
        <el-option
          :value="trademark.id"
          :label="trademark.tmName"
          v-for="(trademark, index) in trademarkArr"
          :key="trademark.id"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述" size="normal">
      <el-input
        type="textarea"
        placeholder="请输入SPU描述"
        v-model="spuParams.description"
      ></el-input>
    </el-form-item>
    <!-- 照片墙 -->
    <el-form-item label="SPU图片" size="normal">
      <el-upload
        v-model:file-list="imgArr"
        action="/api/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
      >
        <el-icon><Plus /></el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
      </el-dialog>
    </el-form-item>
    <!-- 销售属性 -->
    <el-form-item label="销售属性" size="normal">
      <el-select placeholder="请选择" clearable>
        <el-option
          :label="baseAttr.name"
          v-for="(baseAttr, index) in baseSales"
          :key="baseAttr.id"
        ></el-option>
      </el-select>
      <el-button
        style="margin-left: 10px"
        type="primary"
        size="default"
        :icon="Plus"
        >添加销售属性</el-button
      >
    </el-form-item>
    <el-form-item>
      <el-table border style="margin-bottom: 15px" :data="hadSales">
        <el-table-column label="序号" type="index" align="center" width="90px">
        </el-table-column>
        <el-table-column label="属性名" prop="saleAttrName" width="120px">
        </el-table-column>
        <el-table-column label="属性值名称列表">
          <template #="{ row, $index }">
            <el-tag
              type="success"
              size="small"
              style="margin: 0 3px"
              closable
              v-for="(attrValue, index) in row.spuSaleAttrValueList"
              :key="attrValue.id"
              @close="row.spuSaleAttrValueList.splice(index, 1)"
              >{{ attrValue.saleAttrValueName }}</el-tag
            >
            <!-- 编辑模式 -->
            <el-input
              size="small"
              placeholder="请输入属性值"
              clearable
              style="width: 90px"
              v-if="row.show"
              @blur="toLook(row, $index)"
              v-model="row.inputValue"
              :ref="(vc) => (inputArr[$index] = vc)"
            ></el-input>
            <!-- 查看模式 -->
            <el-button
              size="small"
              :icon="Plus"
              v-else
              @click="toEdit(row, $index)"
            ></el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120px">
          <template #="{ row, $index }">
            <el-button
              type="danger"
              size="small"
              :icon="Delete"
              @click="hadSales.splice($index, 1)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-button type="primary" size="small">保存</el-button>
      <el-button size="small" @click="emit('changeScene',0)">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { ref, nextTick } from "vue";
import { Plus, Delete } from "@element-plus/icons-vue";
import type { UploadProps, UploadUserFile } from "element-plus";
import { ElMessage } from "element-plus";
// 引入接口
import {
  reqBaseSaleAttr,
  reqHadSaleAttr,
  reqImgList,
  reqTrademarkData,
} from "@/api/product/spu/spu";
// 照片墙相关的
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
// 删除照片的回调
const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles);
};
// 预览照片的回调
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

// 定义服务器返回的数据
// 品牌
let trademarkArr = ref([]);
// 照片墙
let imgArr = ref([]);
// 基础销售属性
let baseSales = ref([]);
// 已有销售属性
let hadSales = ref([]);

// 定义spu数据
let spuParams = ref<any>({});

// 定义输入框数组数据
let inputArr = ref<any>([]);

// 定义模式,该方案的弊端:一个变量控制多个对象,不能实现一对一控制,不好
// let show = ref<number>(0)

// 定义一个让父组件调用的方法
const getSpuData = async (row) => {
  console.log(row);
  spuParams.value = row;
  // 品牌
  let spu1 = reqTrademarkData();
  // 照片墙
  let spu2 = reqImgList(row.id);
  // 基础销售属性
  let spu3 = reqBaseSaleAttr();
  // 已有销售属性
  let spu4 = reqHadSaleAttr(row.id);
  let result = await Promise.all([spu1, spu2, spu3, spu4]);
  // 存数据
  // 品牌数据
  trademarkArr.value = result[0];
  // 照片墙数据,因为element-Plus封装的照片墙组件需要固定的key值,所以此处使用数组方法 map 来进行修改
  imgArr.value = result[1].map((item) => {
    return {
      name: item.imgName,
      url: item.imgUrl,
    };
  });
  // 基础销售属性
  baseSales.value = result[2];
  // 已有销售属性
  hadSales.value = result[3];
};

// 对外暴露方法,让父组件可以调用
defineExpose({
  getSpuData,
});

// 点击按钮切换为编辑模式
const toEdit = (row, $index) => {
  // 为每个对象添加一个show属性,通过该属性来切换编辑或查看模式
  row.show = true;
  // 获取文本框输入的值
  row.inputValue = "";
  // 切换为编辑模式时聚焦
  nextTick(() => {
    inputArr.value[$index].focus();
  });
};

// 文本框失去焦点切换查看模式
const toLook = (row) => {
  // 需要解决两个问题:
  // 1.文本框不能为空 => 判断
  if (row.inputValue == "") {
    // 提示信息
    ElMessage({
      type: "warning",
      message: "属性值不能为空",
    });
    // 直接返回,不执行以下代码
    return;
  }

  // 2.属性值不能重复,判断当前项和原数组中的元素是否重复
  let repeated = row.spuSaleAttrValueList.find((item) => {
    // 重复则为真,不重复则为假
    return row.inputValue == item.saleAttrValueName;
  });
  // 判断
  // 有重复项
  if (repeated) {
    // 提示信息
    ElMessage({
      type: "warning",
      message: "属性值重复",
    });
    // 清空输入框的值
    row.inputValue = "";
    // 直接返回
    return;
  }
  // 切换为查看模式
  row.show = false;

  // 整理数据:当变为查看模式时需要将文本框中的值添加进数组中
  // 数组中至少得包含两个属性:
  // 1.销售属性的 id (知道是给哪个销售属性添加的属性值);
  // 2.销售属性的属性值
  let newSalesAttrValue = {
    baseSaleAttrId: row.id,
    saleAttrValueName: row.inputValue,
  };
  // 将新值添加进数组中
  row.spuSaleAttrValueList.push(newSalesAttrValue)
  // 清空文本框中的数据
  row.inputValue = ''
};

let emit = defineEmits(['changeScene'])
</script>

<style scoped>
</style>
